/**
 * PItem.java
 * Copyright (C) 2009 Jose Mauro da Silva Sandy
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

package persistencia.notas;

import java.io.IOException;
import java.sql.*;
import plagio.postgres.ConnectionPostgres;
import negocio.notas.Item;
import java.util.*;
import utils.*;

/**
 *
 * @author jmsandy
 */
public class PItem {

    //<editor-fold defaultstate="collapsed" desc="Attributes">
    private boolean error = false;
    //</editor-fold>

    //<editor-fold defaultstate="collapsed" desc="Acessores">
    public boolean isError(){
        return this.error;
    }
    //</editor-fold>

    //<editor-fold defaultstate="collapsed" desc="Table Columns">
    static final protected String K_TBL_Item          = "Item";
    static final protected String K_COL_cod_objeto    = "cod_objeto";
    static final protected String K_COL_idOrcamento   = "identificadororcamento";
    static final protected String K_COL_idNota        = "identificadornota";
    static final protected String K_COL_idProduto     = "produto";
    static final protected String K_COL_quantidade    = "quantidade";
    static final protected String K_COL_valorUnitario = "valorunitario";
    static final protected String K_COL_fatorConv     = "fatorconv";
    static final protected String K_COL_unidCompra    = "unidcompra";
    static final public Integer K_BUSCA_ORCAMENTO   = 1;
    static final public Integer K_BUSCA_NOTA        = 2;    
    //</editor-fold>

    //<editor-fold defaultstate="collapsed" desc="Constructor">
    /**
     * Construtor padrao. Responsavel por realizar a persistencia de um Item
     * @throws java.io.IOException
     */
    public PItem() throws IOException{
        error = false;
    }
    //</editor-fold>

    //<editor-fold defaultstate="collapsed" desc="Methods">
    // Realiza a construcao basica de um select
    protected StringBuilder formSelector(){
        StringBuilder query = new StringBuilder();
        query.append("SELECT " + K_COL_cod_objeto + ", " + K_COL_idOrcamento);
        query.append(", " + K_COL_idNota + ", " + K_COL_idProduto);
        query.append(", " + K_COL_quantidade + ", " + K_COL_valorUnitario+", ");
        query.append(K_COL_fatorConv + ", " + K_COL_unidCompra + " FROM \"");
        query.append(K_TBL_Item + "\"");
        return query;
    }

    /**
     * Responsavel por criar a estrutura para inserir o objeto
     * @return construtor do objeto a ser inserido
     */
    protected String formInsert(){
        return "INSERT INTO \"" + K_TBL_Item + "\"(" + K_COL_cod_objeto +
           ", " + K_COL_idOrcamento + ", " + K_COL_idNota + ", " +
           K_COL_idProduto + ", " + K_COL_quantidade + ", " +
           K_COL_valorUnitario + ", " + K_COL_fatorConv + ", "
           + K_COL_unidCompra + ") VALUES (?, ?, ?, ?, ?, ?, ?, ?)";
    }

    /**
     * Responsavel por criar a estrutura para atualizar o objeto
     * @param obj - Objeto a ser atualizado na base de dados
     * @return construtor do objeto a ser atualizado
     */
    protected String formUpdate(Item obj){
        StringBuilder query = new StringBuilder();
        query.append("UPDATE \"" + K_TBL_Item + "\" SET ");
        query.append(K_COL_idProduto + " = '" + obj.getIdProduto() + "', ");
        query.append(K_COL_quantidade + " = '" + obj.getQuantidade() + "', ");
        query.append(K_COL_valorUnitario + " = '" + obj.getValorUnitario());
        query.append("', " + K_COL_fatorConv+" = '"+obj.getFatorConv() + "', ");
        query.append(K_COL_unidCompra + " = '" + obj.getUnidCompra() + "'");
        query.append(" WHERE " + K_COL_cod_objeto + " = '" +
                                                     obj.getCod_objeto() + "'");
        return query.toString();
    }

    /**
     * Responsavel por criar a estrutura para deletar o objeto
     * @param obj - Objeto a ser deletado na base de dados
     * @return construtor do objeto a ser deletado
     */
    protected String formDelete(Item obj){
        return "DELETE FROM \"" + K_TBL_Item + "\" WHERE " +
                K_COL_cod_objeto + " = '" + obj.getCod_objeto() + "'";
    }

    /**
     * Responsavel por inserir um objeto na base de dados
     * @param obj - objeto a ser inserido na base de dados
     * @return TRUE - caso afirmativo e FALSE - caso contrario
     */
    public Boolean insert(Item obj){
        Boolean status = true;

        try{
            ConnectionPostgres conn = new ConnectionPostgres(); // nova conexao
            // Realiza a conexao com o servidor
            conn = ConnectionSystem.connectionSystem();

            // Monta o objeto em uma instrucao SQL para insercao no banco
            PreparedStatement stat;
            String query = formInsert();
            stat = conn.getConnection().prepareStatement(query);
            stat.setString(1, obj.getCod_objeto());
            stat.setString(2, obj.getIdOrcamento());
            stat.setString(3, obj.getIdNota());
            stat.setString(4, obj.getIdProduto());
            stat.setDouble(5, obj.getQuantidade());
            stat.setDouble(6, obj.getValorUnitario());
            stat.setDouble(7, obj.getFatorConv());
            stat.setString(8, obj.getUnidCompra());
            stat.executeUpdate();
            stat.close();
            conn.closeConnection();
        }
        catch(Exception ex){
            Log.gravarLog(RedirectStackTrace.stackTraceToString(ex), this);
            error = true;
            status = false;
        }
        return status;
    }

    /**
     * Responsavel por atualizar um objeto na base de dados
     * @param obj - objeto a ser atualizado na base de dados
     * @return TRUE - caso afirmativo e FALSE - caso contrario
     */
    public Boolean update(Item obj){
        Boolean status = true;

        try{
            ConnectionPostgres conn = new ConnectionPostgres(); // nova conexao

            // Realiza a conexao com o servidor
            conn = ConnectionSystem.connectionSystem();

            // Monta o objeto em uma instrucao SQL para atualizacao no banco
            PreparedStatement stat;
            String query = formUpdate(obj);
            stat = conn.getConnection().prepareStatement(query);
            stat.executeUpdate();
            stat.close();
            conn.closeConnection();
        }
        catch(Exception ex){
            Log.gravarLog(RedirectStackTrace.stackTraceToString(ex), this);
            error = true;
            status = false;
        }
        return status;
    }

    /**
     * Responsavel por deletar um objeto na base de dados
     * @param obj - objeto a ser deletado na base de dados
     * @return TRUE - caso afirmativo e FALSE - caso contrario
     */
    public Boolean delete(Item obj){
        Boolean status = true;

        try{
            ConnectionPostgres conn = new ConnectionPostgres(); // nova conexao

            // Realiza a conexao com o servidor
            conn = ConnectionSystem.connectionSystem();

            // Monta o objeto em uma instrucao SQL para atualizacao no banco
            PreparedStatement stat;
            String query = formDelete(obj);
            stat = conn.getConnection().prepareStatement(query);
            stat.executeUpdate();
            stat.close();
            conn.closeConnection();
        }
        catch(Exception ex){
            Log.gravarLog(RedirectStackTrace.stackTraceToString(ex), this);
            error = true;
            status = false;
        }
        return status;
    }

    /**
     * Responsavel por recuperar uma lista de itens para uma determinada nota
     * ou orcamento.
     * @param idObj identificador do objeto a ser buscado
     * @param tipoBusca identifica qual busca sera realizada
     * @return lista contendo todos os objetos recuperados
     */
    public ArrayList<Item> recLstItens(String idObj, int tipoBusca){
        // Lista de objetos de retorno
        ArrayList<Item> lstItens = new ArrayList<Item>();
        StringBuilder query = this.formSelector();
        // Clausula where
        if(tipoBusca == K_BUSCA_ORCAMENTO)
            query.append(" WHERE " + K_COL_idOrcamento + " = '" + idObj + "'");
        else
            query.append(" WHERE " + K_COL_idNota + " = '" + idObj + "'");

        try{
            ConnectionPostgres conn = new ConnectionPostgres(); // nova conexao

            // Realiza a conexao com o servidor
            conn = ConnectionSystem.connectionSystem();
            Statement stat = conn.getConnection().createStatement();
            lstItens =  mapear(stat.executeQuery(query.toString()));
        }catch(Exception ex){
            Log.gravarLog(RedirectStackTrace.stackTraceToString(ex), this);
            error = true;
            lstItens = null;
        }
        return lstItens;
    }

    /**
     * Responsavel por converter o objeto vindo do banco de dados para um
     * modelo de objeto
     * @param result - result que obtem toda lista recebida do servidor
     * @return os objetos mapeados
     * @throws java.sql.SQLException
     */
    private ArrayList<Item> mapear(ResultSet result) throws SQLException{
        ArrayList<Item> lstItens = new ArrayList<Item>();

        // Converte todo result recebido para uma lista de objetos
        while(result.next()){
            Item item = new Item();
            item.setCod_objeto(result.getString(1));
            item.setIdOrcamento(result.getString(2));
            item.setIdNota(result.getString(3));
            item.setIdProduto(result.getString(4));
            item.setQuantidade(result.getDouble(5));
            item.setValorUnitario(result.getDouble(6));
            item.setFatorConv(result.getDouble(7));
            item.setUnidCompra(result.getString(8));

            item.setIsNew(false);

            lstItens.add(item);
        }
        return lstItens;
    }
    //</editor-fold>
}